package com.wss.common.widget;

import com.orhanobut.logger.Logger;
import com.wss.common.utils.AnimatorValueUtils;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.ScrollHelper;
import ohos.app.Context;
import ohos.global.configuration.Configuration;

/**
 * Describe：可侧滑ViewGroup，其中子ViewGroup有且只能有2个
 * Created by 吴天强 on 2020/4/20.
 * Copy from: https://github.com/fornana/swipeitemlayout
 */
public class SwipeItemLayout extends ComponentContainer {

    enum Mode {
        RESET, DRAG, FLING, TAP
    }

    private Mode mTouchMode;

    private ComponentContainer mMainView;
    private ComponentContainer mSideView;

    private ScrollRunnable mScrollRunnable;
    private int mScrollOffset;
    private int mMaxScrollOffset;

    private boolean mInLayout;
    private boolean mIsLaidOut;
//    private OnItemSwipeListener onItemSwipeListener;

    public SwipeItemLayout(Context context) {
        this(context, null);
    }

    public SwipeItemLayout(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public SwipeItemLayout(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        mTouchMode = Mode.RESET;
        mScrollOffset = 0;
        mIsLaidOut = false;

        mScrollRunnable = new ScrollRunnable(context);
    }

    public boolean isOpen() {
        return mScrollOffset != 0;
    }

    Mode getTouchMode() {
        return mTouchMode;
    }

    void setTouchMode(Mode mode) {
        switch (mTouchMode) {
            case FLING:
                mScrollRunnable.abort();
                break;
            case RESET:
                break;
        }

        mTouchMode = mode;
    }

    public void open() {
        if (mScrollOffset != -mMaxScrollOffset) {
            //正在open，不需要处理
            if (mTouchMode == Mode.FLING && mScrollRunnable.isScrollToLeft())
                return;

            //当前正在向右滑，abort
            if (mTouchMode == Mode.FLING /*&& !mScrollRunnable.mScrollToLeft*/)
                mScrollRunnable.abort();

            mScrollRunnable.startScroll(mScrollOffset, -mMaxScrollOffset);
        }
    }

    class ScrollRunnable {
        private static final int FLING_DURATION = 200;
        private ScrollHelper mScroller;
        private boolean mAbort;
        private int mMinVelocity;
        private boolean mScrollToLeft;

        ScrollRunnable(Context context) {
            mScroller = new ScrollHelper();
            mAbort = false;
            mScrollToLeft = false;
            mMinVelocity = 50;
        }

        void startScroll(int startX, int endX) {
            if (startX != endX) {
                Logger.e("scroll - startX - endX", "" + startX + " " + endX);
                setTouchMode(Mode.FLING);
                mAbort = false;
                mScrollToLeft = endX < startX;
                mScroller.startScroll(startX, 0, endX - startX, 0);
//                ViewCompat.postOnAnimation(SwipeItemLayout.this, this);
//                if (onItemSwipeListener != null) {
//                    onItemSwipeListener.onItemSwipe(mScrollToLeft);
//                }
            }
        }

        void startFling(int startX, int xVel) {
            Logger.e("fling - startX", "" + startX);

            if (xVel > mMinVelocity && startX != 0) {
                startScroll(startX, 0);
                return;
            }

            if (xVel < -mMinVelocity && startX != -mMaxScrollOffset) {
                startScroll(startX, -mMaxScrollOffset);
                return;
            }

            startScroll(startX, startX > -mMaxScrollOffset / 2 ? 0 : -mMaxScrollOffset);
        }

        void abort() {
            if (!mAbort) {
                mAbort = true;
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
//                    removeCallbacks(this);
                }
            }
        }

        //是否正在滑动需要另外判断
        boolean isScrollToLeft() {
            return mScrollToLeft;
        }


        public void run() {
            Logger.e("abort", Boolean.toString(mAbort));
//            if (!mAbort) {
//                boolean more = mScroller.isOverScrolled();
//                int curX = mScroller.getCurrValue(ScrollHelper.AXIS_X);
//                Logger.e("curX", "" + curX);
//
//                boolean atEdge = trackMotionScroll(curX - mScrollOffset);
//                if (more && !atEdge) {
//                    ViewCompat.postOnAnimation(SwipeItemLayout.this, this);
//                    return;
//                }
//
//                if (atEdge) {
//                    removeCallbacks(this);
//                    if (!mScroller.isFinished())
//                        mScroller.abortAnimation();
//                    setTouchMode(Mode.RESET);
//                }
//
//                if (!more) {
//                    setTouchMode(Mode.RESET);
//                }
//            }
        }

        private void postOnAnimation(int startX, int dx, int duration) {

            final int[] tempX = {startX};

            AnimatorValue animatorValue = new AnimatorValue();
            animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                @Override
                public void onUpdate(AnimatorValue animatorValue, float v) {
                    float animatedValue = AnimatorValueUtils.getAnimatedValue(v, 0, dx);
                    scrollBy(tempX[0], (int) animatedValue);
                    tempX[0] += (int) animatedValue;
                }
            });
            animatorValue.setDuration(duration);
        }
    }
}
